package com.sujeet.learning.caching;

import java.util.HashMap;
import java.util.Map;
import java.util.LinkedList;

public class LruCache<K, V> {
	private Map<K, V> data;
	private LinkedList<K> tracker;
	private int size;
	private Long hits = 0L;
	private Long misses = 0L;

	public LruCache() {
		size = 310;
		data = new HashMap<K, V>(size);
		tracker = new LinkedList<K>();
	}

	public LruCache(int size) {
		data = new HashMap<K, V>(size);
		tracker = new LinkedList<K>();
	}

	public boolean contains(K key) {
		if (data.containsKey(key))
			return true;
		return false;
	}

	public V get(K key) {
		if (data.containsKey(key)) {
			// value found in cache - move the entry up in tracker as it is
			// touched
			moveUp(key);
			++hits;
		}
		return data.get(key);
	}

	public synchronized boolean update(K key, V value) {
		if (data.size() >= size)
			return false;
		if (data.containsKey(key)) {
			return false;
		} else {
			data.put(key, value);
			moveUp(key);
			++misses;
			return true;
		}
	}

	private synchronized void moveUp(K key) {
		tracker.remove(key);
		tracker.addFirst(key);
	}

	public String toString() {
		return data.toString() + " stamps " + tracker.toString();

	}
	
	public Long getHits() {
		return hits;
	}
	

	public Long getMisses() {
		return misses;
	}

}
